/*
 * Copyright 2011 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.locationbasedagent.client;

import com.google.gwt.animation.client.Animation;
import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.EditTextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.text.shared.SafeHtmlRenderer;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.RowStyles;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.Range;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.locationbasedagent.shared.LocationBasedAgentRequestFactory;
import com.locationbasedagent.shared.HouseListingProxy;
import com.locationbasedagent.shared.HouseListingRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class LocationBasedAgentWidget extends Composite {

  interface Binder extends UiBinder<Widget, LocationBasedAgentWidget> {
  }

  public static final Comparator<? super HouseListingProxy> HouseListing_COMPARATOR = new Comparator<HouseListingProxy>() {
    public int compare(HouseListingProxy t0, HouseListingProxy t1) {
      // Sort uncompleted HouseListings above completed HouseListings
      if (isAgent(t0) && !isAgent(t1)) {
        return 1;
      } else if (!isAgent(t0) && isAgent(t1)) {
        return -1;
      } else {
        // Sort HouseListings by due date within each group
        return compareDueDate(t0, t1);
      }
    }

    boolean isAgent(HouseListingProxy t) {
      //Boolean done = t.();
      //return done != null && done;
    	return false;
    }

    int compareDueDate(HouseListingProxy t0, HouseListingProxy t1) {
    /*  Date d0 = t0.getDueDate();
      Date d1 = t1.getDueDate();

      if (d0 == null) {
        if (d1 == null) {
          return 0;
        } else {
          return -1;
        }
      } else if (d1 == null) {
        return 1;
      }
      long delta = d0.getTime() - d1.getTime();
      if (delta < 0) {
        return -1;
      } else if (delta > 0) {
        return 1;
      } else {
        return 0;
      }
      */
    	return 1;
    }
  };

  public static class PropertyListingTable extends CellTable<HouseListingProxy> {

    public Column<HouseListingProxy, String> deleteColumn;
    public Column<HouseListingProxy, String> listingNameColumn;
    public Column<HouseListingProxy, String> listingaddressColumn;
    public Column<HouseListingProxy, String> listingcityColumn;
    public Column<HouseListingProxy, String> listingzipColumn;
    public Column<HouseListingProxy, String> listingSellingAgent;
    public Column<HouseListingProxy, String> sellingAgentNumberColumn;
    public Column<HouseListingProxy, String> latitudeColumn;
    public Column<HouseListingProxy, String> longitudeColumn;
    public Column<HouseListingProxy, String> listingPriceColumn;
    public Column<HouseListingProxy, String> imageURL1;
    public Column<HouseListingProxy, String> imageURL2;
    public Column<HouseListingProxy, String> imageURL3;
    public Column<HouseListingProxy, String> imageURL4;
    public Column<HouseListingProxy, String> imageURL5;
    public Column<HouseListingProxy, String> videoURL;
    
    
    interface HouseListingsTableResources extends CellTable.Resources {
      @Source("HouseListingsTable.css")
      TableStyle cellTableStyle();
    }

    interface TableStyle extends CellTable.Style {
      String columnListingName();

      String columnListingAddress();
      
      String columnListingCity();
      
      String columnListingZip();
      
      String columnListingSellingAgentNumber();
      
      String columnlatitude();
      
      String columnlongitude();
      
      String columnListingPrice();
      
      String columnimageURL1();
      
      String columnimageURL2();
      
      String columnimageURL3();
      
      String columnimageURL4();
      
      String columnimageURL5();
      
      String columnvideoURL();
      
      String columnTrash();
    
    }

    private static HouseListingsTableResources resources = GWT.create(HouseListingsTableResources.class);

    public PropertyListingTable() {
      super(20, resources);


      listingNameColumn = new Column<HouseListingProxy, String>(new EditTextCell()) {
        @Override
        public String getValue(HouseListingProxy object) {
          return object.getListingName();
        }
      };
      addColumn(listingNameColumn, "Description");
      addColumnStyleName(0, "columnFill");
      addColumnStyleName(0, resources.cellTableStyle().columnListingName());

      listingaddressColumn = new Column<HouseListingProxy, String>(new EditTextCell()) {
          @Override
          public String getValue(HouseListingProxy object) {
            return object.getListingAddress();
          }
        };
        addColumn(listingaddressColumn, "Address");
        addColumnStyleName(1, "columnFill");
        addColumnStyleName(1, resources.cellTableStyle().columnListingAddress());
      
        listingcityColumn = new Column<HouseListingProxy, String>(new EditTextCell()) {
            @Override
            public String getValue(HouseListingProxy object) {
              return object.getListingCity();
            }
          };
          addColumn(listingcityColumn, "City");
          addColumnStyleName(2, "columnFill");
          addColumnStyleName(2, resources.cellTableStyle().columnListingCity());
          
          listingzipColumn = new Column<HouseListingProxy, String>(new EditTextCell()) {
              @Override
              public String getValue(HouseListingProxy object) {
                return object.getListingZip();
              }
            };
            addColumn(listingzipColumn, "Zip Code");
            addColumnStyleName(3, "columnFill");
            addColumnStyleName(3, resources.cellTableStyle().columnListingZip());
      
            listingPriceColumn = new Column<HouseListingProxy, String>(new EditTextCell()) {
                @Override
                public String getValue(HouseListingProxy object) {
                  return object.getListingPrice();
                }
              };
              addColumn(listingPriceColumn, "Price");
              addColumnStyleName(4, "columnFill");
              addColumnStyleName(4, resources.cellTableStyle().columnListingPrice());
      
      
      ButtonCell buttonCell = new ButtonCell(new SafeHtmlRenderer<String>() {
        public SafeHtml render(String object) {
          return SafeHtmlUtils.fromTrustedString("<img src=\"delete.png\"></img>");
        }

        public void render(String object, SafeHtmlBuilder builder) {
          builder.append(render(object));
        }
      });

      deleteColumn = new Column<HouseListingProxy, String>(buttonCell) {
        @Override
        public String getValue(HouseListingProxy object) {
          return "\u2717"; // Ballot "X" mark
        }
      };
      addColumn(deleteColumn, "\u2717");
      addColumnStyleName(5, resources.cellTableStyle().columnTrash());
    }
  }
  
  class AndroidAnimation extends Animation {
    private static final int TOP = -50;
    private static final int BOTTOM = 150;
    Element element;

    public AndroidAnimation(Element element) {
      this.element = element;
    }

    @Override
    protected void onStart() {
      element.getStyle().setTop(TOP, Unit.PX);
    }

    @Override
    protected void onUpdate(double progress) {
      element.getStyle().setTop(TOP + (BOTTOM - TOP) * interpolate(progress), Unit.PX);
    }

    @Override
    protected void onComplete() {
      element.getStyle().setTop(TOP, Unit.PX);
    }
  }

  private static final int DELAY_MS = 1000;

  private static Binder uiBinder = GWT.create(Binder.class);


  @UiField
  TextBox listingName;

  @UiField
  TextBox listingAddress;

  @UiField
  TextBox listingCity;
  
  @UiField
  TextBox listingZip;
  
  @UiField
  TextBox latitude;
  
  @UiField
  TextBox longitude;
  
  @UiField
  TextBox listingPrice;
  
  @UiField
  TextBox listingSellingAgentNumber;
  
  @UiField
  TextBox listingImage1;
  @UiField
  TextBox listingImage2;
  @UiField
  TextBox listingImage3;
  @UiField
  TextBox listingImage4;
  @UiField
  TextBox listingImage5;
  
  @UiField
  TextBox listingVideo;

  
  @UiField
  PropertyListingTable propertyListingTable;

  private final EventBus eventBus = new SimpleEventBus();
  private final LocationBasedAgentRequestFactory requestFactory = GWT
      .create(LocationBasedAgentRequestFactory.class);
  private List<HouseListingProxy> HouseListingsList;

  public LocationBasedAgentWidget() {
    initWidget(uiBinder.createAndBindUi(this));

    requestFactory.initialize(eventBus);

    ListDataProvider<HouseListingProxy> listDataProvider = new ListDataProvider<HouseListingProxy>();
    listDataProvider.addDataDisplay(propertyListingTable);
    HouseListingsList = listDataProvider.getList();

    Element androidElement = getElement().getFirstChildElement().getFirstChildElement();
    final Animation androidAnimation = new AndroidAnimation(androidElement);

    propertyListingTable.setRowStyles(new RowStyles<HouseListingProxy>() {
      public String getStyleNames(HouseListingProxy row, int rowIndex) {
        Range visibleRange = propertyListingTable.getVisibleRange();
        int lastRow = visibleRange.getStart() + visibleRange.getLength() - 1;
        if (rowIndex == HouseListingsList.size() - 1 || rowIndex == lastRow) {
          return isDone(row) ? "HouseListing complete last" : "HouseListing incomplete last";
        } else {
          return isDone(row) ? "HouseListing complete" : "HouseListing incomplete";
        }
      }
    });
    
    propertyListingTable.listingNameColumn.setFieldUpdater(new FieldUpdater<HouseListingProxy, String>() {
        public void update(int index, HouseListingProxy HouseListing, String value) {
          HouseListingRequest request = requestFactory.listingRequest();
          HouseListingProxy updatedHouse = request.edit(HouseListing); 
          updatedHouse.setListingName(value);
          requestFactory.listingRequest().queryHouseListings("UPDATE", updatedHouse.getId().toString(), value, "", "", "", "", "", "", "", "", "", "", "", "", "", "").fire(new Receiver<List<HouseListingProxy>>() {
              @Override
              public void onSuccess(List<HouseListingProxy> HouseListings) {
                if (HouseListings.size() > 0) {
                  //signin.setText("Logged in as ");// + HouseListings.get(0).getEmailAddress());
                }

                // sort first
                ArrayList<HouseListingProxy> sortedHouseListings = new ArrayList<HouseListingProxy>(HouseListings);
                Collections.sort(sortedHouseListings, HouseListing_COMPARATOR);

                HouseListingsList.clear();
                for (HouseListingProxy HouseListing : sortedHouseListings) {
                  HouseListingsList.add(HouseListing);
                }
              }
            });
        }
      });
    
    propertyListingTable.listingaddressColumn.setFieldUpdater(new FieldUpdater<HouseListingProxy, String>() {
        public void update(int index, HouseListingProxy HouseListing, String value) {
          HouseListingRequest request = requestFactory.listingRequest();
          HouseListingProxy updatedHouse = request.edit(HouseListing); 
          updatedHouse.setListingName(value);
          requestFactory.listingRequest().queryHouseListings("UPDATE", updatedHouse.getId().toString(), "", value, "", "", "", "", "", "", "", "", "", "", "", "", "").fire(new Receiver<List<HouseListingProxy>>() {
              @Override
              public void onSuccess(List<HouseListingProxy> HouseListings) {
                if (HouseListings.size() > 0) {
                  //signin.setText("Logged in as ");// + HouseListings.get(0).getEmailAddress());
                }

                // sort first
                ArrayList<HouseListingProxy> sortedHouseListings = new ArrayList<HouseListingProxy>(HouseListings);
                Collections.sort(sortedHouseListings, HouseListing_COMPARATOR);

                HouseListingsList.clear();
                for (HouseListingProxy HouseListing : sortedHouseListings) {
                  HouseListingsList.add(HouseListing);
                }
              }
            });
        }
      });
    
    propertyListingTable.listingcityColumn.setFieldUpdater(new FieldUpdater<HouseListingProxy, String>() {
        public void update(int index, HouseListingProxy HouseListing, String value) {
          HouseListingRequest request = requestFactory.listingRequest();
          HouseListingProxy updatedHouse = request.edit(HouseListing); 
          updatedHouse.setListingName(value);
          requestFactory.listingRequest().queryHouseListings("UPDATE", updatedHouse.getId().toString(), "", "", value, "", "", "", "", "", "", "", "", "", "", "", "").fire(new Receiver<List<HouseListingProxy>>() {
              @Override
              public void onSuccess(List<HouseListingProxy> HouseListings) {
                if (HouseListings.size() > 0) {
                  //signin.setText("Logged in as ");// + HouseListings.get(0).getEmailAddress());
                }

                // sort first
                ArrayList<HouseListingProxy> sortedHouseListings = new ArrayList<HouseListingProxy>(HouseListings);
                Collections.sort(sortedHouseListings, HouseListing_COMPARATOR);

                HouseListingsList.clear();
                for (HouseListingProxy HouseListing : sortedHouseListings) {
                  HouseListingsList.add(HouseListing);
                }
              }
            });
        }
      });
    
    propertyListingTable.listingzipColumn.setFieldUpdater(new FieldUpdater<HouseListingProxy, String>() {
        public void update(int index, HouseListingProxy HouseListing, String value) {
          HouseListingRequest request = requestFactory.listingRequest();
          HouseListingProxy updatedHouse = request.edit(HouseListing); 
          updatedHouse.setListingName(value);
          requestFactory.listingRequest().queryHouseListings("UPDATE", updatedHouse.getId().toString(), "", "", "", value, "", "", "", "", "", "", "", "", "", "", "").fire(new Receiver<List<HouseListingProxy>>() {
              @Override
              public void onSuccess(List<HouseListingProxy> HouseListings) {
                if (HouseListings.size() > 0) {
                  //signin.setText("Logged in as ");// + HouseListings.get(0).getEmailAddress());
                }

                // sort first
                ArrayList<HouseListingProxy> sortedHouseListings = new ArrayList<HouseListingProxy>(HouseListings);
                Collections.sort(sortedHouseListings, HouseListing_COMPARATOR);

                HouseListingsList.clear();
                for (HouseListingProxy HouseListing : sortedHouseListings) {
                  HouseListingsList.add(HouseListing);
                }
              }
            });
        }
      });
    
    propertyListingTable.listingPriceColumn.setFieldUpdater(new FieldUpdater<HouseListingProxy, String>() {
        public void update(int index, HouseListingProxy HouseListing, String value) {
          HouseListingRequest request = requestFactory.listingRequest();
          HouseListingProxy updatedHouse = request.edit(HouseListing); 
          updatedHouse.setListingName(value);
          requestFactory.listingRequest().queryHouseListings("UPDATE", updatedHouse.getId().toString(), "", "", "", "", "", "", "", "", value, "", "", "", "", "", "").fire(new Receiver<List<HouseListingProxy>>() {
              @Override
              public void onSuccess(List<HouseListingProxy> HouseListings) {
                if (HouseListings.size() > 0) {
                  //signin.setText("Logged in as ");// + HouseListings.get(0).getEmailAddress());
                }

                // sort first
                ArrayList<HouseListingProxy> sortedHouseListings = new ArrayList<HouseListingProxy>(HouseListings);
                Collections.sort(sortedHouseListings, HouseListing_COMPARATOR);

                HouseListingsList.clear();
                for (HouseListingProxy HouseListing : sortedHouseListings) {
                  HouseListingsList.add(HouseListing);
                }
              }
            });
        }
      });

    propertyListingTable.deleteColumn.setFieldUpdater(new FieldUpdater<HouseListingProxy, String>() {
      public void update(int index, HouseListingProxy HouseListing, String value) {
        HouseListingRequest request = requestFactory.listingRequest();
        request.deleteHouseListing(HouseListing.getId()).fire(new Receiver<Void>() {
            @Override
            public void onSuccess( Void s) {
              System.out.println("I was successful");
              }
          });
        HouseListingsList.remove(HouseListing);
      }
    });

    listingName.getElement().setPropertyString("placeholder", "Enter listing description here");
    listingAddress.getElement().setPropertyString("placeholder", "Enter listing address here");
    listingCity.getElement().setPropertyString("placeholder", "Enter listing city here");
    listingZip.getElement().setPropertyString("placeholder", "Enter listing zip code here");
    latitude.getElement().setPropertyString("placeholder", "Enter listing latitude here");
    longitude.getElement().setPropertyString("placeholder", "Enter listing longitude here");
    listingPrice.getElement().setPropertyString("placeholder", "Enter listing price here");
    listingImage1.getElement().setPropertyString("placeholder", "Enter image URL here");
    listingImage2.getElement().setPropertyString("placeholder", "Enter image URL here");
    listingImage3.getElement().setPropertyString("placeholder", "Enter image URL here");
    listingImage4.getElement().setPropertyString("placeholder", "Enter image URL here");
    listingImage5.getElement().setPropertyString("placeholder", "Enter image URL here");
    listingVideo.getElement().setPropertyString("placeholder", "Enter video URL here");
    


   
        retrieveHouseListings();

  }

  boolean isDone(HouseListingProxy t) {
   // Boolean done = t.isAgent();
    return false;//done != null && done;
  }

  private void retrieveHouseListings() {
    requestFactory.listingRequest().queryHouseListings("", "","","", "", "", "", "", "", "", "", "", "", "", "", "", "").fire(new Receiver<List<HouseListingProxy>>() {
      @Override
      public void onSuccess(List<HouseListingProxy> HouseListings) {
        if (HouseListings.size() > 0) {
          //signin.setText("Logged in as ");// + HouseListings.get(0).getEmailAddress());
        }

        // sort first
        ArrayList<HouseListingProxy> sortedHouseListings = new ArrayList<HouseListingProxy>(HouseListings);
        Collections.sort(sortedHouseListings, HouseListing_COMPARATOR);

        HouseListingsList.clear();
        for (HouseListingProxy HouseListing : sortedHouseListings) {
          HouseListingsList.add(HouseListing);
        }
      }
    });
  }
  
  private void populateDatastore() {
	  requestFactory.listingRequest().queryHouseListings("POPULATE", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "").fire(new Receiver<List<HouseListingProxy>>() {
	      @Override
	      public void onSuccess(List<HouseListingProxy> HouseListings) {
	        if (HouseListings.size() > 0) {
	          //signin.setText("Logged in as ");// + HouseListings.get(0).getEmailAddress());
	        }

	        // sort first
	        ArrayList<HouseListingProxy> sortedHouseListings = new ArrayList<HouseListingProxy>(HouseListings);
	        Collections.sort(sortedHouseListings, HouseListing_COMPARATOR);

	        HouseListingsList.clear();
	        for (HouseListingProxy HouseListing : sortedHouseListings) {
	          HouseListingsList.add(HouseListing);
	        }
	      }
	    });
  }

  /**
   * Send a HouseListing to the server.
   */
  private void sendNewPropertyInfoToServer(String message) {
    HouseListingRequest request = requestFactory.listingRequest();
    
//    MessageRequest requestForMessage = requestFactory.messageRequest();
//    MessageProxy messageProxy = requestForMessage.create(MessageProxy.class);
//    System.out.println("Sending new Property data to server !! ");
    String name = listingName.getText();
    request.createHouseListing(listingName.getText(), listingAddress.getText(), listingCity.getText(),listingZip.getText(), 
    		"", listingSellingAgentNumber.getText(), "37.380055", "-122.114959", listingPrice.getText(), 
    		listingImage1.getText(), listingImage2.getText(), listingImage3.getText(), listingImage4.getText(), listingImage5.getText(),
            listingVideo.getText()).fire(new Receiver<HouseListingProxy>() {
            //"http://daily3gp.com/vids/reporter_hit_by_plane.3gp").fire(new Receiver<HouseListingProxy>() {
        @Override
        public void onSuccess(HouseListingProxy HouseListings) {
          //System.out.println("I was successful");
          }
      });
    retrieveHouseListings();

    	
    
    //HouseListing.setDueDate(new Date());
    System.out.println("Sent new Property data to server !! ");
   // Request<List<HouseListingProxy>> list = request.queryHouseListings("", "", "");
   // request.updateHouseListing(HouseListing).fire();
    //list.
   // HouseListingsList.add(HouseListing);
  }
  
  @UiHandler("createproperty")
  void handleCreateClick(ClickEvent e) {
    //Window.alert("Hello, AJAX");
      String message = listingAddress.getText();
      //listingAddress.setText("");
      sendNewPropertyInfoToServer(message);      
      //androidAnimation.run(400);
  }
  
  @UiHandler("listproperty")
  void handleListClick(ClickEvent e) {
    retrieveHouseListings();
  }
  
 @UiHandler("populate")
 void handlePopulateClick(ClickEvent e) {
	 populateDatastore();
 }

  
  
  
  
  
  
}

